#!/bin/python3
# -*- coding:utf-8 -*-
"""
    [模块名]
    By :陈狍子 e4ting@qq.com 2024-12-07 22:18:51
"""
import sys,os
from pdb import set_trace as strace
from traceback  import format_exc as dumpstack
from e4ting import util,log
import itertools

from .const import all_flushs,map_cards,init_texas_cache
from .cash  import Utxo,VirtualAccount
from .pot   import RewardPot

from core.cache   import PlayerCache

class Judge():
    """ 裁判 """
    def __init__(self, btn=0, game=None):
        # super(GameRound, self).__init__()
        self.players = []
        self.btn     = btn
        self.common  = []
        self.game    = game
        self.room    = game.room
        self.minimum = 10
        self.uid     = game.uid

    def init(self):
        self.account = VirtualAccount(uid=f"judge{self.uid}") # 裁判，所有玩家的下注积分，都存在裁判这里
        self.account.create_record(name=f"裁判-{self.uid}", detail=f"房间{self.room.uid}的裁判")
        self.account.init()

    @property
    def cache(self):
        cache = PlayerCache(self.uid)
        if not cache.exists():
            cache.set(__time__=util.now())
        return cache

    def broadcast(self, msg):
        return self.room.broadcast(msg)

    def send_commons(self, msg):
        return self.room.send_commons(msg)

    def send_all_hands(self, msg):
        return self.room.send_all_hands(msg)

    def send_players_pos(self):
        return self.room.sender.all_rates([ {"card_type": player.get("pos", "")} for player in self.players ])

    @property
    def sblind(self):
        """ 小盲 """
        return (self.btn + 1)% len(self.players)

    @property
    def bblind(self):
        """ 大盲 """
        return (self.btn + 2)% len(self.players)

    @property
    def utg(self):
        """ 枪口位，仅首轮有 """
        return (self.btn + 3) % len(self.players)

    def set_players(self, players):
        self.players = players

        self.players[self.btn% len(self.players)].set("pos", "Dealer")
        self.players[self.utg].set("pos", "枪口")
        self.players[self.sblind].set("pos", "小盲")
        self.players[self.bblind].set("pos", "大盲")
        self.send_players_pos()

    def set_common(self, common):
        self.common = common
        data = [ face.webdump(hiden=True) for face in self.common ]
        self.send_commons(data)

    def get_player_score(self, player):
        engines = [Engine(cards) for cards in itertools.combinations(self.common + player.faces, 5)]
        scores = [ eng.calc_score() for eng in engines]
        ret = max(scores)
        player.set_score(ret)

    def get_winner(self):
        """ 计算赢家 """
        for player in self.players:
            self.get_player_score(player)

        win = max(self.players)
        winner = [_ for _ in self.players if _ >= win]
        log.info(f"赢家是 : {winner}")
        self.broadcast(str(winner))
        return winner

    # 分发奖励
    def rewards(self):
        # RewardPot()
        utxo = Utxo(who=self.account, to=self.room.dealer, room=self.room, game=self.game)
        utxo(int(self.account), reason='游戏奖励')

    def __repr__(self):
        if self.common:
            return "{doc} 公牌 {self.common}".format(doc=self.__doc__.strip(), self=self)
        return self.__doc__.strip()

    def quit(self):
        self.account.delete()

class Score():
    def __init__(self, score=0, **kwargs):
        self.score = score
        [ setattr(self, k , v) for k,v in kwargs.items()]

    def webdump(self):
        return dict(card_type=self.type, score=self.score)

    def __lt__(self, other):
        return self.score < other.score

    def __ge__(self, other):
        return self.score >= other.score

    def __le__(self, other):
        return self.score <= other.score

    def __repr__(self):
        return f"{self.cards} => {self.type} => {self.score}"

class Engine():
    def __init__(self, cards):
        self.cards  = cards
        # 这个函数全局只会调用一次
        init_texas_cache(0)
        self.init()

    def init(self):
        self.flush = ''.join([card.color for card in self.cards])

        count = [ card.count for card in self.cards ]
        if self.flush in all_flushs:
            count.append('f')
        count.sort()
        self.count = "".join(count)

    def calc_score(self, cards=[]):
        """ 卡BUG，同花顺和葫芦、同花顺和金刚，同一个玩家无法同时抓到，所以先找金刚和葫芦，这两个搜索起来相对简单"""
        ret = map_cards[self.count]
        return Score(**dict(ret, cards=self.cards))